package com.cskaoyan.javase.oop3._1interface._0introduction;

/**
 * 接口的引入
 *
 * 我们就迫切需要一种全新的数据类型，这种全新的数据类型：
 *      1.不强调属性，只强调行为的抽象，"继承"它表示功能的扩展。
 *      2.在一个类继承某个类后，还能继续"继承"，不受Java单继承限制。
 *      3.没有"is-a"这种继承关系的限制。
 *      3.最好还有抽象方法。（因为它能表示规范和标准）
 * 这种全新的数据类型，就是接口（interface）。
 *
 * 接口完全不同于类,接口也不是类
 *
 * 上面四条，其实已经描述了接口的特点
 * 接口是一种表示对行为抽象的，不受Java单继承限制的
 * 用来作为功能扩展标准的一种引用数据类型。
 *
 * 它的定义语法如下：
 * [访问权限修饰符] interface 接口名{}
 * 解释:
 *      1.类和接口是平行关系的数据类型,都是引用数据类型,它们在定义时使用的关键字不同
 *      2.访问权限修饰符和接口名基本和类名一样,大驼峰
 * 有些程序员喜欢在接口前加一个大写字母I来表示该类型是一个接口，可以借鉴，但不强制。
 *      3.接口是可以被一个类"继承"的，接口的"继承"
 *      更准确、常见的叫法称之为接口的实现。
 *      当然它也不再使用extends关键字，而是使用 implements 关键字。
 *      一个普通类实现接口必须实现所有抽象方法。
 *      它的语法是：
 *      [访问权限修饰符] class 类名 extends 类名 implements 接口名 {}
 *      细节问题：如果一个类实现接口并继承别的类，要"先继承再实现"。关键字位置不要写反了。
 *     4.在接口的实现中，可以称呼接口为"父接口"，接口的实现类为"子类"
 *     它们仍然是父子关系。当然多态现象仍然能够发生。
 *
 *     5.接口不受但继承限制，一个类可以在继承别的类的同时实现接口，而且可以实现多个接口。
 *
 * @since 16:59
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 接口ITraining是父接口,它的实现类也就是子类
        ITraining it;
        it = new SuperCat();
        it.walkUpRight();
        it = new SuperDog();
        it.walkUpRight();

        // 目前SuperDog对象,可以用几个引用指向呢?排除Object
        SuperDog sd = new SuperDog();
        Dog d = new SuperDog();
        ITraining it2 = new SuperDog();
        IA ia = new SuperDog();
    }
}

abstract class Animal {
    public abstract void shout();
}

class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("猫叫");
    }
}

class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("狗叫");
    }
}

class SuperCat extends Cat implements ITraining {
    @Override
    public void walkUpRight() {
        System.out.println("我是超威蓝猫,我直立行走也是很正常的!");
    }
}

class SuperDog extends Dog implements ITraining, IA {
    @Override
    public void walkUpRight() {
        System.out.println("我是超级天狗,我直立行走也是很正常的!");
    }

    @Override
    public void test() {
        System.out.println("test");
    }
}

abstract class AbstractTraining {
    public abstract void walkUpRight();
}

interface ITraining {
    public abstract void walkUpRight();
}

interface IA {
    public abstract void test();
}